#include "register_and_login.h"
#include "Upload_database.h"
#include "check_login.h"
#include "admin_function.h"
#include "user_function.h"
#include "cyclic_reception.h"
#include "sys_log.h"
#include "heart_beat.h"

// 收到数据并回发
void register_and_login_recv(int listenfd)
{
    // 判断标志位
    int admin_judge = 0;
    int user_judge = 0;

    // 用于存储返回值的变量
    static int ret = 0;
    int res = 0;

    // 定义缓冲区变量
    char buf[MAXSIZE] = {0};

    // 循环等待客户端的登录或注册信息
    while (1)
    {
        // 提示信息
        printf("服务器在等待登录或者注册信息----\n");
        LOG_I("服务器在等待登录或者注册信息\n");
        memset(buf, 0, sizeof(buf));

        // 接收客户端数据
        ret = recv(listenfd, buf, sizeof(buf), 0);
        if (ret == -1)
        {
            perror("recv");
            exit(-1);
        }
        // 接收到数据，处理客户端消息
        if (ret > 0)
        {
            handle_client_message(listenfd, buf); // 正常处理消息并更新心跳时间
        }

        // 打印接收到的数据
        // puts(buf);

        // 定义状态信息结构体变量
        STA count;
        memset(&count, 0, sizeof(STA));

        // 定义数据解包结构体变量
        USE dat;
        memset(&dat, 0, sizeof(USE));
        // 解析客户端发送的JSON数据
        dat = unpack_login(buf);

        // 管理员
        if (dat.type == 1)
        {
            // 登录
            if (dat.user_type == 1)
            {
                // 检查登录信息
                res = check_login1(&dat);
                if (res == 0)
                {
                    count.type = 0;
                    strcpy(count.state, "账号或密码错误，请重新输入");
                    // 回发消息
                    Postback_message(listenfd, &count);
                }
                else if (res == 1)
                {
                    count.type = 1;
                    strcpy(count.state, "管理员登录成功");
                    LOG_I("管理员登录成功\n");
                    // 回发消息
                    Postback_message(listenfd, &count);
                    admin_judge = 1;
                    break;
                }
            }
            // 注册
            else if (dat.user_type == 2)
            {
                strcpy(count.state, "管理员注册成功");
                LOG_I("管理员注册成功\n");
                count.type = 1;
                // 回发消息
                Postback_message(listenfd, &count);
                // 插入数据库
                MYSQL *dbconnect = NULL;
                // 链接数据库
                dbconnect = connect_mysql();
                // 获取管理员数据并插入数据库
                data_insert_database(&dat, dbconnect);
                mysql_close(dbconnect);
            }
        }

        // 用户
        else if (dat.type == 2)
        {
            // 登录
            if (dat.user_type == 1)
            {
                // 检查登录信息
                res = check_login2(&dat);
                if (res == 0)
                {
                    count.type = 0;
                    strcpy(count.state, "账号或密码错误，请重新输入");
                    // 回发消息
                    Postback_message(listenfd, &count);
                }
                else if (res == 1)
                {
                    count.type = 1;
                    LOG_I("用户登录成功\n");
                    strcpy(count.state, "用户登录成功");
                    // 回发消息
                    Postback_message(listenfd, &count);
                    user_judge = 1;
                    break;
                }
            }
            else if (dat.user_type == 2)
            {
                count.type = 1;
                strcpy(count.state, "用户注册成功");
                LOG_I("用户注册成功\n");

                // 插入数据库
                MYSQL *dbconnect = NULL;
                // 链接数据库
                dbconnect = connect_mysql();
                // 获取用户数据并插入数据库
                data_insert_database2(&dat, dbconnect);
                // 回发消息
                Postback_message(listenfd, &count);
                mysql_close(dbconnect);
            }
        }
    }
    // 根据登录结果调用相应的功能处理函数
    if (admin_judge == 1)
    {
        // 管理员操作
        admin_function(admin_judge, listenfd);
    }
    else if (user_judge == 1)
    {
        // 用户操作
        user_function(user_judge, listenfd);
    }
}

// 发送回文
void Postback_message(int listenfd, STA *count)
{
    cJSON *json = NULL;
    static int ret = 0;
    json = cJSON_CreateObject();
    cJSON_AddItemToObject(json, "type", cJSON_CreateNumber(count->type));
    cJSON_AddItemToObject(json, "state", cJSON_CreateString(count->state));

    char *dest = cJSON_Print(json);
    printf("服务器在回发数据--------------\n");

    // 检查 listenfd 的有效性
    if (listenfd < 0)
    {
        perror("监听套接字描述符无效!");
        free(dest);
        cJSON_Delete(json);
        return;
    }

    ret = send(listenfd, dest, MAXSIZE, 0);
    // printf("回发的数据是：%s\n", dest);
    LOG_I("服务器回发数据成功\n");
    if (ret == -1)
    {
        perror("send");
        exit(-1);
        LOG_E("服务器在回发数据时失败\n");
    }
    free(dest); // 释放打印出来的字符串
    cJSON_Delete(json);
}

// 解析JSON
USE unpack_login(char *buf)
{

    USE dat;
    memset(&dat, 0, sizeof(USE));
    cJSON *json = NULL;
    json = cJSON_Parse(buf);

    cJSON *node = NULL;

    node = cJSON_GetObjectItem(json, "type");
    if (node == NULL)
    {
        LOG_E("register1can't find type\n");
        printf("register1can't find type\n");
        exit(-1);
    }
    if (node->type == cJSON_Number)
    {
        dat.type = node->valueint;
    }

    node = cJSON_GetObjectItem(json, "user_type");
    if (node == NULL)
    {
        LOG_E("register2can't find user_type\n");
        printf("register2can't find user_type\n");
        exit(-1);
    }
    if (node->type == cJSON_Number)
    {
        dat.user_type = node->valueint;
    }

    node = cJSON_GetObjectItem(json, "user_name");
    if (node == NULL)
    {
        LOG_E("register3can't find user_name\n");
        printf("register3can't find user_name\n");
        exit(-1);
    }
    if (node->type == cJSON_String)
    {
        strcpy(dat.user_name, node->valuestring);
    }

    node = cJSON_GetObjectItem(json, "user_password");
    if (node == NULL)
    {
        LOG_E("register4can't find user_password\n");
        printf("register4can't find user_password\n");
        exit(-1);
    }
    if (node->type == cJSON_String)
    {
        strcpy(dat.user_password, node->valuestring);
    }
    cJSON_Delete(json);
    return dat;
}